Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkg/wakaama: add DTLS support #16233

Merged
merged 8 commits into from
May 7, 2024

Conversation

leandrolanzieri
Copy link
Contributor

@leandrolanzieri leandrolanzieri commented Mar 25, 2021

Contribution description

This PR adds support for DTLS connections when using LwM2M. The LwM2M client implementation has been rewritten to allow both CoAP and CoAP over DTLS to be used at the same time. An own implementation of the Security Object is introduced, as it needs to handle the interaction with the Credential Manager (credman).
For now only Pre-Shared Key mode is supported. Pre-Shared Key and Raw Public Key modes are supported. DTLS is supported during the communication with LwM2M server and during bootstrapping.

Update: Raw public key mode is added now as well.

The example application has been modified to use DTLS connections by default. Finally, documentation has been improved.

Testing procedure

The best way to test this is using the example/wakaama application. If you use Eclipse Leshan as your LwM2M Server implementation, you should see an indication that the connection is done over DTLS:

leshan

leshan_02

The example can be modified to use plain CoAP connection to the server. That should also work as usual.

diff --git a/examples/wakaama/lwm2m_cli.c b/examples/wakaama/lwm2m_cli.c
index 0cecb7b73a..8d7392746b 100644
--- a/examples/wakaama/lwm2m_cli.c
+++ b/examples/wakaama/lwm2m_cli.c
@@ -63,8 +63,8 @@ void lwm2m_cli_init(void)
     lwm2m_obj_security_args_t args = {
         .server_id = CONFIG_LWM2M_SERVER_SHORT_ID,
         .server_uri = CONFIG_LWM2M_SERVER_URI,
-        .security_mode = LWM2M_SECURITY_MODE_PRE_SHARED_KEY,
-        .cred = &credential,
+        .security_mode = LWM2M_SECURITY_MODE_NONE,
+        .cred = NULL,
         .is_bootstrap = false, /* set to true when using Bootstrap server */
         .client_hold_off_time = 5,
         .bootstrap_account_timeout = 0

Issues/PRs references

Depends on #16179 (merged)
Depends on #16203 (merged)
Depends on #16709 (merged)

@leandrolanzieri leandrolanzieri added Type: new feature The issue requests / The PR implemements a new feature for RIOT Area: pkg Area: External package ports State: waiting for other PR State: The PR requires another PR to be merged first Area: security Area: Security-related libraries and subsystems labels Mar 25, 2021
@leandrolanzieri
Copy link
Contributor Author

Rebased, now that #16179 is merged

@Ollrogge
Copy link
Member

Ollrogge commented Aug 3, 2021

Successfully tested this using the nrf52840dongle as LwM2M client connected to a border router (gnrc_border_router) running on a nrf52840dk. For some reason it did not work when I tried using the dongle as border router and the dk as LwM2M client. The /dev/ttyACM device kept disappearing in this case.

Below is a screenshot of the LwM2M server dashboard showing the device and DTLS connection info.

DeepinScreenshot_select-area_20210804003030

Additionally the console output for the lwm2m client:

2021-08-04 00:43:36,577 # lwm2m start
2021-08-04 00:43:36,579 # [lwm2m_init:64] Entering
2021-08-04 00:43:36,580 # [lwm2m_configure:277] numObject: 3
2021-08-04 00:43:36,581 # [lwm2m_configure:297] endpointName: "testRIOTDevice"
2021-08-04 00:43:36,582 # [lwm2m:client:refresh_cred] refreshing DTLS credentials
2021-08-04 00:43:36,582 # [lwm2m_data_new:143] size: 1
2021-08-04 00:43:36,583 # [lwm2m_data_encode_int:272] value: 
2021-08-04 00:43:36,584 # [lwm2m_data_encode_int:273] 0 
2021-08-04 00:43:36,585 # [lwm2m_data_free:161] size: 1
2021-08-04 00:43:36,586 # [lwm2m:client] trying to add credential with tag 11
2021-08-04 00:43:36,586 # [lwm2m:client] added
2021-08-04 00:43:36,587 # [lwm2m_step:376] timeoutP: 
2021-08-04 00:43:36,587 # [lwm2m_step:377] 1 
2021-08-04 00:43:36,588 # [lwm2m_step:382] State: STATE_INITIAL
2021-08-04 00:43:36,590 # [object_getServers:741] Entering
2021-08-04 00:43:36,591 # [lwm2m_data_new:143] size: 3
2021-08-04 00:43:36,592 # [lwm2m_data_encode_bool:410] value: false
2021-08-04 00:43:36,593 # [lwm2m_data_encode_int:272] value: 
2021-08-04 00:43:36,594 # [lwm2m_data_encode_int:273] 1 
2021-08-04 00:43:36,595 # [lwm2m_data_encode_int:272] value: 
2021-08-04 00:43:36,596 # [lwm2m_data_encode_int:273] 5 
2021-08-04 00:43:36,598 # [lwm2m_data_decode_bool:420] Entering
2021-08-04 00:43:36,600 # [lwm2m_data_decode_bool:471] result: 1, value: false
2021-08-04 00:43:36,601 # [lwm2m_data_decode_int:283] Entering
2021-08-04 00:43:36,602 # [lwm2m_data_decode_int:338] result: 1, value: 
2021-08-04 00:43:36,603 # [lwm2m_data_decode_int:339] 1 
2021-08-04 00:43:36,604 # [lwm2m_data_new:143] size: 1
2021-08-04 00:43:36,606 # [lwm2m_data_encode_int:272] value: 
2021-08-04 00:43:36,607 # [lwm2m_data_encode_int:273] 1 
2021-08-04 00:43:36,608 # [lwm2m_data_decode_int:283] Entering
2021-08-04 00:43:36,609 # [lwm2m_data_decode_int:338] result: 1, value: 
2021-08-04 00:43:36,610 # [lwm2m_data_decode_int:339] 1 
2021-08-04 00:43:36,611 # [lwm2m_data_free:161] size: 1
2021-08-04 00:43:36,612 # [lwm2m_data_new:143] size: 2
2021-08-04 00:43:36,614 # [lwm2m_data_encode_int:272] value: 
2021-08-04 00:43:36,615 # [lwm2m_data_encode_int:273] 300 
2021-08-04 00:43:36,616 # [lwm2m_data_encode_string:195] "U"
2021-08-04 00:43:36,617 # [lwm2m_data_decode_int:283] Entering
2021-08-04 00:43:36,619 # [lwm2m_data_decode_int:338] result: 1, value: 
2021-08-04 00:43:36,620 # [lwm2m_data_decode_int:339] 300 
2021-08-04 00:43:36,621 # [lwm2m_data_free:161] size: 2
2021-08-04 00:43:36,622 # [lwm2m_data_free:161] size: 3
2021-08-04 00:43:36,624 # [registration_start:477] State: STATE_REGISTER_REQUIRED
2021-08-04 00:43:36,626 # [object_getRegisterPayloadBufferLength:508] Entering
2021-08-04 00:43:36,627 # [object_getRegisterPayload:579] Entering
2021-08-04 00:43:36,628 # [lwm2m_data_new:143] size: 1
2021-08-04 00:43:36,631 # [lwm2m_data_encode_string:195] "coaps://[2003:fa:9f08:1800:b81c:7238:d99e:6aba]:5684"
2021-08-04 00:43:36,632 # [lwm2m_data_free:161] size: 1
2021-08-04 00:43:36,633 # [lwm2m_data_new:143] size: 1
2021-08-04 00:43:36,634 # [lwm2m_data_encode_bool:410] value: false
2021-08-04 00:43:36,635 # [lwm2m_data_free:161] size: 1
2021-08-04 00:43:36,636 # [lwm2m_data_new:143] size: 1
2021-08-04 00:43:36,638 # [lwm2m_data_encode_int:272] value: 
2021-08-04 00:43:36,639 # [lwm2m_data_encode_int:273] 0 
2021-08-04 00:43:36,640 # [lwm2m_data_free:161] size: 1
> 2021-08-04 00:43:36,787 # [lwm2m:client:PSK] getting credential
2021-08-04 00:43:36,787 # [lwm2m_data_new:143] size: 1
2021-08-04 00:43:36,789 # [lwm2m_data_encode_string:195] "coaps://[2003:fa:9f08:1800:b81c:7238:d99e:6aba]:5684"
2021-08-04 00:43:36,790 # [lwm2m_data_free:161] size: 1
2021-08-04 00:43:36,791 # [lwm2m:client:PSK] found matching EP on instance 1
2021-08-04 00:43:36,791 # [lwm2m:client:PSK] tag: 11
2021-08-04 00:43:36,868 # [transaction_new:155] method: 2, mID: 26188, token_len: 4
2021-08-04 00:43:36,869 # [transaction_new:159] NULL
2021-08-04 00:43:36,871 # [transaction_new:237] Exiting on success. new transac=0x20007c38
2021-08-04 00:43:36,873 # [transaction_send:353] Entering: transaction=0x20007c38
2021-08-04 00:43:36,875 # [observe_step:492] Entering
2021-08-04 00:43:36,877 # [registration_step:1303] State: STATE_REGISTERING
2021-08-04 00:43:36,878 # [transaction_step:436] Entering
2021-08-04 00:43:36,879 # [lwm2m_step:485] Final timeoutP:
2021-08-04 00:43:36,880 # [lwm2m_step:486] 1 
2021-08-04 00:43:36,881 # [lwm2m_step:488] Final state: STATE_REGISTERING
2021-08-04 00:43:36,882 # [lwm2m:client] state: STATE_REGISTERING
2021-08-04 00:43:36,968 # [lwm2m:client] finding connection
2021-08-04 00:43:36,968 # [lwm2m:client] handle packet (22 bytes)
2021-08-04 00:43:36,969 # [lwm2m_handle_packet:214] Entering
2021-08-04 00:43:36,972 # [lwm2m_handle_packet:218] Parsed: ver 1, type 2, tkl 4, code 2.01, mid 26188, Content type: 0
2021-08-04 00:43:36,973 # [lwm2m_handle_packet:220] Payload: 
2021-08-04 00:43:36,974 # [transaction_handleResponse:276] Entering
2021-08-04 00:43:36,976 # [prv_handleRegistrationReply:212] Registration successful
2021-08-04 00:43:36,978 # [transaction_remove:262] Entering. transaction=0x20007c38
2021-08-04 00:43:36,980 # [transaction_free:248] Entering. transaction=0x20007c38
2021-08-04 00:43:37,883 # [lwm2m_step:376] timeoutP: 
2021-08-04 00:43:37,884 # [lwm2m_step:377] 1 
2021-08-04 00:43:37,885 # [lwm2m_step:382] State: STATE_REGISTERING
2021-08-04 00:43:37,887 # [registration_getStatus:506] State: STATE_REGISTERING
2021-08-04 00:43:37,888 # [registration_getStatus:513] targetP->status: STATE_REGISTERED
2021-08-04 00:43:37,890 # [registration_getStatus:536] reg_status: STATE_REGISTERED
2021-08-04 00:43:37,891 # [observe_step:492] Entering
2021-08-04 00:43:37,893 # [registration_step:1303] State: STATE_READY
2021-08-04 00:43:37,894 # [transaction_step:436] Entering
2021-08-04 00:43:37,895 # [lwm2m_step:485] Final timeoutP:
2021-08-04 00:43:37,895 # [lwm2m_step:486] 1 
2021-08-04 00:43:37,897 # [lwm2m_step:488] Final state: STATE_READY
2021-08-04 00:43:37,897 # [lwm2m:client] state: STATE_READY
2021-08-04 00:43:38,898 # [lwm2m_step:376] timeoutP: 
2021-08-04 00:43:38,899 # [lwm2m_step:377] 1 
2021-08-04 00:43:38,900 # [lwm2m_step:382] State: STATE_READY
2021-08-04 00:43:38,902 # [registration_getStatus:506] State: STATE_READY
2021-08-04 00:43:38,903 # [registration_getStatus:513] targetP->status: STATE_REGISTERED
2021-08-04 00:43:38,905 # [registration_getStatus:536] reg_status: STATE_REGISTERED
2021-08-04 00:43:38,906 # [observe_step:492] Entering
2021-08-04 00:43:38,908 # [registration_step:1303] State: STATE_READY
2021-08-04 00:43:38,909 # [transaction_step:436] Entering
2021-08-04 00:43:38,910 # [lwm2m_step:485] Final timeoutP:
2021-08-04 00:43:38,910 # [lwm2m_step:486] 1 
2021-08-04 00:43:38,912 # [lwm2m_step:488] Final state: STATE_READY
2021-08-04 00:43:38,912 # [lwm2m:client] state: STATE_READY
2021-08-04 00:43:39,440 # Exiting Pyterm

@PeterKietzmann
Copy link
Member

For some reason it did not work when I tried using the dongle as border router and the dk as LwM2M client

@Ollrogge is this related to #16411? If so, please report your outcome there.

@github-actions github-actions bot added Area: build system Area: Build system Area: doc Area: Documentation Area: examples Area: Example Applications Area: Kconfig Area: Kconfig integration Area: network Area: Networking labels Aug 4, 2021
@MrKevinWeiss
Copy link
Contributor

So far testing has not gone that well. Further investigation is needed before we can proceed. It is crashing on both the samr21-xpro and feather-nrf52840-sense.

@MrKevinWeiss
Copy link
Contributor

Some documentation additions I will just throw here as well:

Running with security

In the security section click 'Add Security Information', select the security mode
'Pre-Shared Key', and enter the Client endpoint name and the security information
(Identity and Key).

Then Endpoint should be what is configured in the client device, CONFIG_LWM2M_DEVICE_NAME.
For example, the default name is "testRIOTDevice".

Assuming Security Mode is psk, the Identity field should match the CONFIG_LWM2M_PSK_ID value.
By default, it is Client_Identity.

The final field, the Key field is CONFIG_LWM2M_PSK_KEY.
The default is ThisIsRIOT! but it must be converted to hex. The hex conversion can be done as you
wish but here is a quick example with bash:

echo -n "ThisIsRIOT!" | xxd -p
54686973497352494f5421

Bootstrap server (optional)

@leandrolanzieri
Copy link
Contributor Author

Looks like something changed in the meantime, and the stack size of the event thread was not big enough now. I updated this in the example Makefile now. Tested with the feather-nrf52840-sense board.

@MrKevinWeiss
Copy link
Contributor

I just tested with a master rebase, aside from documentation updates I think this looks good, I would also like to try on the samr21-xpro maybe...

@MrKevinWeiss
Copy link
Contributor

oi oi oi, also some native64 fixes are needed I guess

@leandrolanzieri
Copy link
Contributor Author

Let's see if the prints are fixed now

@leandrolanzieri
Copy link
Contributor Author

Looks like I finally got it right

@MrKevinWeiss
Copy link
Contributor

Just going though a runthrough and noticed some things:

diff --git a/examples/lwm2m/README.md b/examples/lwm2m/README.md
index dc13c58c46..7849691962 100644
--- a/examples/lwm2m/README.md
+++ b/examples/lwm2m/README.md
@@ -41,7 +41,7 @@ Router, you might want to specify:
 java -jar ./leshan-server-demo.jar -lh fd00:dead:beef::1
ESCAPE BACKTICK```
 
-In the security section click 'Add new client security configuration', select the security mode
+In the security section click 'Add Security Information', select the security mode
 'Pre-Shared Key', and enter the Client endpoint name and the security information
 (Identity and Key).
 
@@ -73,8 +73,8 @@ BS_COAPSPORT=5686
 BS_WEBPORT=8888
 
 # run the server
-java -jar ./leshan-bsserver-demo.jar --coapport ${BS_COAPPORT} \
-            --coapsport ${BS_COAPSPORT} --webport ${BS_WEBPORT}
+java -jar ./leshan-bsserver-demo.jar --coap-port ${BS_COAPPORT} \
+            --coaps-port ${BS_COAPSPORT} --web-port ${BS_WEBPORT}
ESCAPE BACKTICK```
 
 To set up the configuration of the node and the server:

I don't know how much knowledge we ca assume of the target audience... but if it is very little I think I can help refine the documentation a bit more.

Can you squash and just update the args?

@leandrolanzieri
Copy link
Contributor Author

Done

Copy link
Contributor

@MrKevinWeiss MrKevinWeiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK, tested the pre-squash and it worked. Looking at the code (quite a bit) looks OK too.

@MrKevinWeiss MrKevinWeiss enabled auto-merge May 6, 2024 14:57
@MrKevinWeiss MrKevinWeiss added this pull request to the merge queue May 6, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 6, 2024
@leandrolanzieri
Copy link
Contributor Author

Updated Makefile.ci

@leandrolanzieri leandrolanzieri enabled auto-merge May 7, 2024 08:38
@leandrolanzieri leandrolanzieri added this pull request to the merge queue May 7, 2024
Merged via the queue into RIOT-OS:master with commit 67f183d May 7, 2024
25 checks passed
@leandrolanzieri
Copy link
Contributor Author

Thanks for the review! Nice to see this merged 😃

@leandrolanzieri leandrolanzieri deleted the pr/pkg/wakaama_dtls branch May 7, 2024 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: build system Area: Build system Area: doc Area: Documentation Area: examples Area: Example Applications Area: Kconfig Area: Kconfig integration Area: pkg Area: External package ports Area: security Area: Security-related libraries and subsystems CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.